package com.ham.mud.commands.skills;

import com.ham.mud.ServerConnection;
import com.ham.mud.Targetable;
import com.ham.mud.TargetableService;
import com.ham.mud.characters.player.Player;
import com.ham.mud.commands.KillCommand;
import com.ham.mud.commands.PlayerCommand;
import com.ham.mud.rooms.Room;
import com.ham.mud.rooms.RoomService;
import com.ham.mud.state.CombatState;
import com.ham.mud.state.ConnectionState;
import com.ham.mud.state.PVPState;

/**
 * Created by hlucas on Jun 27, 2011 at 12:52:35 PM
 */
public abstract class Skill extends PlayerCommand {
    @Override
    public void execute(ServerConnection connection, String[] params) {
        Player player = connection.getPlayer();
        int atX = player.getAtX();
        int atY = player.getAtY();
        Room room = RoomService.getRoom(player.getZone(), atX, atY);
        ConnectionState state = connection.getState();

        if(params.length == 0) {
            if(isCombatSkill() && !((state instanceof CombatState) || (state instanceof PVPState))) {
                connection.printSolo("You can only do that during combat.");
                return;
            }

            if(state instanceof CombatState) {
                useSkill(connection, ((CombatState) state).getCombatWith(), null);
            } else if(state instanceof PVPState){
                useSkill(connection, ((PVPState)state).getEnemy());
            } else {
                useSkill(connection, null, null);
            }
            return;
        }

        String target = params[0];
        Targetable targetable = TargetableService.findTarget(target, room.getMobs(), room.getOtherPlayers(connection));
        if(targetable == null) {
            connection.printSolo("You can't see that here.");
            return;
        }

        if(isCombatSkill()) {
            KillCommand kc = new KillCommand();
            kc.execute(connection, params);
        }

        if(state instanceof PVPState){
            useSkill(connection, ((PVPState)state).getEnemy());
        } else {
            useSkill(connection, targetable, null);
        }
    }

    private void useSkill(ServerConnection connection, ServerConnection enemy) {
        useSkill(connection, enemy.getPlayer(), enemy);
    }

    protected abstract void useSkill(ServerConnection connection, Targetable targetable, ServerConnection enemy);
    protected abstract boolean isCombatSkill();
    public abstract int getRounds();
    public abstract String getName();
}
